package controllers

import (
    "errors"
    "image"
    "image/gif"
    "image/jpeg"
    "image/png"
    "log"
    "os"
    "path/filepath"
    "strings"
)

type ImageControl struct {
}

func (this *ImageControl) Trimming(before_filename string, after_filename string, x, y, w, h int) {
    src, err := this.LoadImage(before_filename)
    if err != nil {
        log.Println("load image fail..")
    }

    img1, err := this.ImageCopy(src, x, y, w, h)
    if err != nil {
        log.Println("image copy fail...")
    }

    img := this.Rotate270(img1)

    saveErr := this.SaveImage(after_filename, img)
    if saveErr != nil {
        log.Println("save image fail..")
    }
}

func (this *ImageControl) LoadImage(path string) (img image.Image, err error) {
    file, err := os.Open(path)
    if err != nil {
        return
    }
    defer file.Close()
    img, _, err = image.Decode(file)

    return
}

func (this *ImageControl) SaveImage(p string, src image.Image) error {
    f, err := os.OpenFile(p, os.O_SYNC|os.O_RDWR|os.O_CREATE, 0666)

    if err != nil {
        return err
    }
    defer f.Close()
    ext := filepath.Ext(p)

    if strings.EqualFold(ext, ".jpg") || strings.EqualFold(ext, ".jpeg") {

        err = jpeg.Encode(f, src, &jpeg.Options{Quality: 80})

    } else if strings.EqualFold(ext, ".png") {
        err = png.Encode(f, src)
    } else if strings.EqualFold(ext, ".gif") {
        err = gif.Encode(f, src, &gif.Options{NumColors: 256})
    }
    return err
}

func (this *ImageControl) ImageCopy(src image.Image, x, y, w, h int) (image.Image, error) {

    var subImg image.Image

    if rgbImg, ok := src.(*image.YCbCr); ok {
        subImg = rgbImg.SubImage(image.Rect(x, y, x+w, y+h)).(*image.YCbCr) //图片裁剪x0 y0 x1 y1
    } else if rgbImg, ok := src.(*image.RGBA); ok {
        subImg = rgbImg.SubImage(image.Rect(x, y, x+w, y+h)).(*image.RGBA) //图片裁剪x0 y0 x1 y1
    } else if rgbImg, ok := src.(*image.NRGBA); ok {
        subImg = rgbImg.SubImage(image.Rect(x, y, x+w, y+h)).(*image.NRGBA) //图片裁剪x0 y0 x1 y1
    } else if rgbImg, ok := src.(*image.Paletted); ok {
        subImg = rgbImg.SubImage(image.Rect(x, y, x+w, y+h)).(*image.Paletted) //图片裁剪x0 y0 x1 y1
    } else {
        return subImg, errors.New("图片解码失败")
    }

    return subImg, nil
}

// 旋转90度
func  (this *ImageControl)Rotate90(m image.Image) image.Image {
    rotate90 := image.NewRGBA(image.Rect(0, 0, m.Bounds().Dy(), m.Bounds().Dx()))
    // 矩阵旋转
    for x := m.Bounds().Min.Y; x < m.Bounds().Max.Y; x++ {
        for y := m.Bounds().Max.X - 1; y >= m.Bounds().Min.X; y-- {
            //  设置像素点
            rotate90.Set(m.Bounds().Max.Y-x, y, m.At(y, x))
        }
    }
    return rotate90
}

// 旋转270度
func (this *ImageControl)Rotate270(m image.Image) image.Image {
    rotate270 := image.NewRGBA(image.Rect(0, 0, m.Bounds().Dy(), m.Bounds().Dx()))
    // 矩阵旋转
    for x := m.Bounds().Min.Y; x < m.Bounds().Max.Y; x++ {
        for y := m.Bounds().Max.X - 1; y >= m.Bounds().Min.X; y-- {
            // 设置像素点
            //rotate270.Set(x, m.Bounds().Max.X-y, m.At(y, x)) 减去偏移（m.Bounds().Min.Y）修复旋转空白bug
            rotate270.Set(x - m.Bounds().Min.Y, m.Bounds().Max.X-y, m.At(y, x))
        }
    }
    return rotate270
}

func (this *ImageControl)Paste(m image.Image, rect image.Rectangle, offset image.Point)  image.Image  {
    paste := image.NewRGBA(image.Rect(0, 0, rect.Dx(), rect.Dy()))
    for x := m.Bounds().Min.X; x < m.Bounds().Max.X; x++ {
        for y := m.Bounds().Min.Y; y < m.Bounds().Max.Y; y++ {
            // 设置像素点
            paste.Set(x+offset.X - m.Bounds().Min.X, y+offset.Y - m.Bounds().Min.Y, m.At(x, y))
        }
    }
    return paste
}
